home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Resources / Developers / XAMPP 1.5.4 / Windows installer / xampp-win32-1.5.4-installer.exe / xampp / php / pear / Stream / Var.php < prev   
Encoding:
PHP Script  |  2005-07-07  |  13.1 KB  |  470 lines

  1. <?PHP
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2002 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Stephan Schmidt <schst@php-tools.net>                       |
  17. // |          partly based on an exmple by Wez Furlong                    |
  18. // +----------------------------------------------------------------------+
  19. //
  20. //    $Id: Var.php,v 1.3 2004/10/31 14:52:18 schst Exp $
  21.  
  22. /**
  23.  * stream is readable
  24.  * This depends on the mode, that is used for opening the stream
  25.  */
  26. define("STREAM_VAR_READABLE", 1);
  27.  
  28. /**
  29.  * stream is writeable
  30.  * This depends on the mode, that is used for opening the stream
  31.  */
  32. define("STREAM_VAR_WRITEABLE", 2);
  33.  
  34. /**
  35.  * Stream wrapper to access a variable
  36.  *
  37.  * Stream wrappers allow you to access any datasource using PHP's file manipulation functions
  38.  * like fopen(), fclose(), fseek(), ftell(),.. as well as directory functions like 
  39.  * opendir() readdir() and closedir().
  40.  *
  41.  * This wrapper allows you to access any variable using these functions.
  42.  * You have to specify a scope (GLOBALS, _GET, _POST, etc.) as the host and
  43.  * the variable name as the path. If you want to access a string, that is
  44.  * stored in an array, you can use this array like you would use a directory.
  45.  *
  46.  * Usage:
  47.  * <code>
  48.  *  require_once '../Var.php';
  49.  *  stream_wrapper_register( "var", "Stream_Var" );
  50.  *
  51.  *  $fp = fopen('var://GLOBALS/myArray/index','r');
  52.  *  $data = fread($fp,100);
  53.  *  fclose($fp);
  54.  * </code>
  55.  *
  56.  * This wrapper also has support for dir functions, so it's possible to read any array, like
  57.  * you would read a directory. The following code will list all keys in an array.
  58.  * You could use fopen() to read the values for the keys.
  59.  *
  60.  * <code>
  61.  *  require_once '../Var.php';
  62.  *  stream_wrapper_register( "var", "Stream_Var" );
  63.  *
  64.  *  $dh = opendir('var://_SERVER');
  65.  *  while ($entry = readdir($dh)) {
  66.  *      echo $entry."<br />";
  67.  *  }
  68.  *  closedir($dh);
  69.  * </code>
  70.  *
  71.  * This wrapper allows you to replace files and directories with structures in
  72.  * memory in any application, that relies on filesystem functions. But keep in mind
  73.  * that variables are not persistent during several request, unless you write to
  74.  * var://SESSION.
  75.  * But this can be used to replace temporary files with variables.
  76.  *
  77.  * @category Stream
  78.  * @package  Stream_Var
  79.  * @version  0.2.1
  80.  * @author   Stephan Schmidt <schst@php-tools.net>
  81.  */
  82. class Stream_Var {
  83.  
  84.    /**
  85.     * pointer to the variable
  86.     * @var mixed   $_pointer
  87.     */
  88.     var $_pointer = null;
  89.  
  90.    /**
  91.     * flag to indicate whether stream is open
  92.     * @var boolean   $_open
  93.     */
  94.     var $_open = false;
  95.  
  96.    /**
  97.     * position
  98.     * @var integer $_pos
  99.     */
  100.     var $_pos = 0;
  101.  
  102.    /**
  103.     * mode of the opened filw
  104.     * @var integer   $_mode
  105.     */
  106.     var $_mode = 0;
  107.  
  108.    /**
  109.     * method used by fopen
  110.     *
  111.     * @access public
  112.     * @param  string  $path        path to the variable (e.g. var://GLOBALS/myArray/anyIndex)
  113.     * @param  string  $mode        mode to open the stream, like 'r', 'w,',... ({@see fopen()})
  114.     * @param  array   $options     options (not implemented yet)
  115.     * @param  string  $opened_path this will be set to the actual opened path
  116.     * @return boolean $success
  117.     */
  118.     function stream_open($path, $mode, $options, &$opened_path)
  119.     {
  120.         $url = parse_url($path);
  121.  
  122.         $scope   = $url["host"];
  123.         $varpath = substr($url["path"], 1);
  124.         
  125.         $mode = strtolower($mode);
  126.         switch ($mode{0}) {
  127.             case    "r":
  128.                 $status = $this->_setPointer($scope, $varpath, false);
  129.                 $this->_mode = $this->_mode | STREAM_VAR_READABLE;
  130.                 break;
  131.             case    "w":
  132.             case    "a":
  133.                 $status = $this->_setPointer($scope, $varpath, true);
  134.                 $this->_mode = $this->_mode | STREAM_VAR_WRITEABLE;
  135.                 break;
  136.             case    "x":
  137.                 $status = $this->_setPointer($scope, $varpath, false);
  138.                 if ($status) {
  139.                     return false;
  140.                 }
  141.                 $status = $this->_setPointer($scope, $varpath, true);
  142.                 $this->_mode = $this->_mode | STREAM_VAR_WRITEABLE;
  143.                 break;
  144.         }
  145.  
  146.         if (!$status) {
  147.             return  false;
  148.         }
  149.         
  150.         if (!is_scalar($this->_pointer)) {
  151.             return false;
  152.         }
  153.  
  154.         // start at zero
  155.         $this->_pos = 0;
  156.         $this->_open = true;
  157.         $opened_path = $path;
  158.  
  159.         if ($mode{0} == 'a') {
  160.             $this->stream_seek(0, SEEK_END);
  161.         }
  162.  
  163.         if (strlen($mode) > 1 && $mode{1} == '+') {
  164.             $this->_mode = $this->_mode | STREAM_VAR_READABLE | STREAM_VAR_WRITEABLE;
  165.         }
  166.  
  167.         return true;
  168.     }
  169.  
  170.    /**
  171.     * check for end of stream
  172.     *
  173.     * @access public
  174.     * @return boolean $eof  true if at end of stream
  175.     */
  176.     function stream_eof()
  177.     {
  178.         return ($this->_pos >= strlen($this->_pointer));
  179.     }
  180.  
  181.    /**
  182.     * return the current position
  183.     *
  184.     * @access public
  185.     * @return integer $position current position in stream
  186.     */
  187.     function stream_tell()
  188.     {
  189.         return $this->_pos;
  190.     }
  191.  
  192.    /**
  193.     * close the stream
  194.     *
  195.     * @access public
  196.     */
  197.     function stream_close()
  198.     {
  199.         $this->_pos  = 0;
  200.         $this->_open = false;
  201.     }
  202.  
  203.    /**
  204.     * read from the stream
  205.     *
  206.     * @access public
  207.     * @param  integer $count    amount of bytes to read
  208.     * @return string  $data     data that has been read
  209.     */
  210.     function stream_read($count)
  211.     {
  212.         if (!$this->_open) {
  213.             return false;
  214.         }
  215.  
  216.         if (!($this->_mode & STREAM_VAR_READABLE)) {
  217.             return false;
  218.         }
  219.  
  220.         $data = substr($this->_pointer, $this->_pos, $count);
  221.         $this->_pos = $this->_pos + strlen($data);
  222.         return $data;
  223.     }
  224.  
  225.    /**
  226.     * write to the stream
  227.     *
  228.     * @access public
  229.     * @param  mixed   $data  data to write
  230.     * @return integer $bytes number of bytes that were written
  231.     */
  232.     function stream_write($data)
  233.     {
  234.         if (!$this->_open) {
  235.             return false;
  236.         }
  237.         
  238.         if (!($this->_mode & STREAM_VAR_WRITEABLE)) {
  239.             return false;
  240.         }
  241.         
  242.         $datalen = strlen($data);
  243.        
  244.         $this->_pointer = substr($this->_pointer, 0, $this->_pos) . $data . substr($this->_pointer, $this->_pos+$datalen);
  245.         $this->_pos = $this->_pos + $datalen;
  246.         return $datalen;
  247.     }
  248.  
  249.    /**
  250.     * move the position in the stream
  251.     *
  252.     * @access public
  253.     * @param  integer $offset  offset
  254.     * @return integer $whence  point from which the offset should be calculated
  255.     */
  256.     function stream_seek($offset, $whence)
  257.     {
  258.         switch ($whence) {
  259.             //  from start
  260.             case SEEK_SET:
  261.                 if ($offset < strlen($this->_pointer) && $offset >= 0) {
  262.                      $this->_pos = $offset;
  263.                      return true;
  264.                 } else {
  265.                      return false;
  266.                 }
  267.                 break;
  268.             // from current position
  269.             case SEEK_CUR:
  270.                 if ($offset >= 0) {
  271.                      $this->_pos += $offset;
  272.                      return true;
  273.                 } else {
  274.                      return false;
  275.                 }
  276.                 break;
  277.             // from the end
  278.             case SEEK_END:
  279.                 if (strlen($this->_pointer) + $offset >= 0) {
  280.                      $this->_pos = strlen($this->_pointer) + $offset;
  281.                      return true;
  282.                 } else {
  283.                      return false;
  284.                 }
  285.                 break;
  286.             default:
  287.                 return false;
  288.         }
  289.     }
  290.  
  291.    /**
  292.     * write all data to storage
  293.     *
  294.     * @access public
  295.     */
  296.     function stream_flush()
  297.     {
  298.         return true;
  299.     }
  300.  
  301.    /**
  302.     * return information about the stream
  303.     *
  304.     * @access public
  305.     * @return array $stat   information about the stream (currently only the length is included)
  306.     */
  307.     function stream_stat()
  308.     {
  309.         $stat = array(
  310.                       'size' => strlen($this->_pointer)
  311.                     );
  312.         return $stat;
  313.     }
  314.  
  315.  
  316.    /**
  317.     * open 'directory'
  318.     *
  319.     * @access public
  320.     * @param  string    $path    path to the array (i.e. the directory)
  321.     * @param  array     $options not implemented, yet.
  322.     * @return boolean   $success
  323.     */
  324.     function dir_opendir($path, $options)
  325.     {
  326.         $url = parse_url($path);
  327.  
  328.         $scope   = $url['host'];
  329.         if (isset($url['path'])) {
  330.             $varpath = substr($url['path'], 1);
  331.         } else {
  332.             $varpath = '';
  333.         }
  334.         
  335.         if (!$status = $this->_setPointer($scope, $varpath))
  336.             return  false;
  337.  
  338.         if (!is_array($this->_pointer)) {
  339.             return false;
  340.         }
  341.         reset($this->_pointer);
  342.         $this->_open = true;
  343.         return true;
  344.     }
  345.  
  346.  
  347.    /**
  348.     * close 'directory'
  349.     *
  350.     * @access public
  351.     * @return boolean $success
  352.     */
  353.     function dir_closedir()
  354.     {
  355.         $this->_open = false;
  356.         return true;
  357.     }
  358.  
  359.    /**
  360.     * rewind 'directory'
  361.     *
  362.     * @access public
  363.     * @return boolean $success
  364.     */
  365.     function dir_rewinddir()
  366.     {
  367.         if (!$this->_open) {
  368.             return false;
  369.         }
  370.         reset($this->_pointer);
  371.         return true;
  372.     }
  373.  
  374.    /**
  375.     * read one entry from 'directory'
  376.     *
  377.     * @access public
  378.     * @return mixed  $entry entry that has been read, or false if there are no entries left  
  379.     */
  380.     function dir_readdir()
  381.     {
  382.         if (!$this->_open) {
  383.             return false;
  384.         }
  385.         if (current($this->_pointer) == count($this->_pointer)-1) {
  386.             return false;
  387.         }
  388.         list($key) = each($this->_pointer);
  389.         return $key;
  390.     }
  391.  
  392.    /**
  393.     * set the internal pointer
  394.     *
  395.     * Basically this method only sets the object property _pointer
  396.     * as a reference to a variable
  397.     *
  398.     * @access private
  399.     * @param  string  $scope    scope of the variable: GLOBAL, GET, POST, COOKIE, SESSION, SERVER, ENV
  400.     * @param  string  $path     path to the variable. Array indices are seperated by a slash
  401.     * @param  boolean $create   create the variable, if it does not exist
  402.     */
  403.     function _setPointer($scope, $path, $create = false )
  404.     {
  405.         $varpath = explode("/", $path);
  406.  
  407.         switch (strtoupper($scope)) {
  408.             // GET variables
  409.             case    "GET":
  410.             case    "_GET":
  411.                 $this->_pointer = &$_GET;
  412.                 break;
  413.  
  414.             // POST variables
  415.             case    "POST":
  416.             case    "_POST":
  417.                 $this->_pointer = &$_POST;
  418.                 break;
  419.  
  420.             // SERVER variables
  421.             case    "SERVER":
  422.             case    "_SERVER":
  423.                 $this->_pointer = &$_SERVER;
  424.                 break;
  425.  
  426.             // SESSION variables
  427.             case    "SESSION":
  428.             case    "_SESSION":
  429.                 $this->_pointer = &$_SESSION;
  430.                 break;
  431.  
  432.             // COOKIE variables
  433.             case    "COOKIE":
  434.             case    "_COOKIE":
  435.                 $this->_pointer = &$_COOKIE;
  436.                 break;
  437.  
  438.             // ENV variables
  439.             case    "ENV":
  440.             case    "_ENV":
  441.                 $this->_pointer = &$_ENV;
  442.                 break;
  443.  
  444.             // global variables
  445.             case    "GLOBALS":
  446.             default:
  447.                 $this->_pointer = &$GLOBALS;
  448.                 break;
  449.             
  450.         }
  451.         if (empty($varpath)) {
  452.             return true;
  453.         }
  454.  
  455.         while ($part = array_shift($varpath)) {
  456.             if (!isset($this->_pointer[$part])) {
  457.                 if (!$create) {
  458.                     return false;
  459.                 }
  460.                 if (!empty($varpath)) {
  461.                     return false;
  462.                 }
  463.                 $this->_pointer[$part] = '';
  464.             }
  465.             $this->_pointer = &$this->_pointer[$part];
  466.         }        
  467.         return true;
  468.     }
  469. }
  470. ?>